package com.wans.guli.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.wans.guli.product.constant.em.AttrTypeEnum;
import com.wans.guli.product.entity.AttrAttrgroupRelationEntity;
import com.wans.guli.product.entity.AttrEntity;
import com.wans.guli.product.entity.CategoryEntity;
import com.wans.guli.product.service.AttrAttrgroupRelationService;
import com.wans.guli.product.service.AttrService;
import com.wans.guli.product.service.CategoryService;
import com.wans.guli.product.vo.AttrAttrgroupRelationRestVO;
import com.wans.guli.product.vo.AttrGroupVO;
import com.wans.guli.product.vo.AttrRespVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wans.guli.common.utils.PageUtils;
import com.wans.guli.common.utils.Query;

import com.wans.guli.product.dao.AttrGroupDao;
import com.wans.guli.product.entity.AttrGroupEntity;
import com.wans.guli.product.service.AttrGroupService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service("attrGroupService")
@SuppressWarnings("all")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private AttrService attrService;
    @Autowired
    private AttrAttrgroupRelationService attrAttrgroupRelationService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<AttrGroupEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageByCatId(Long catId, Map<String, Object> params) {
        // 请求参数key获取
        String key = (String) params.get("key");
        // 请求参数key是否为空
        boolean empty = StringUtils.isEmpty(key);


        IPage<AttrGroupEntity> page = this.lambdaQuery()
                .eq(catId != 0, AttrGroupEntity::getCatelogId, catId)
                .and(!empty, consumer ->
                        consumer.like(AttrGroupEntity::getAttrGroupName, key)
                                .or()
                                .like(AttrGroupEntity::getDescript, key)
                                .or()
                                .like(AttrGroupEntity::getIcon, key)
                                .or()
                                .like(AttrGroupEntity::getSort, key)
                ).page(new Query<AttrGroupEntity>().getPage(params));

        return new PageUtils(page);

    }

    @Override
    public AttrGroupEntity getInfoById(Long attrGroupId) {
        // 用于存放分类路径
        LinkedList<Long> catelogPath = new LinkedList<>();

        AttrGroupEntity attrGroupEntity = this.getById(attrGroupId);

        //TODO 获取分类路径 - 递归查询数据库 - 性能可能会差
        getCatelogPath(attrGroupEntity.getCatelogId(), catelogPath);
        AttrGroupVO attrGroupVO = new AttrGroupVO();
        // 属性转换
        BeanUtil.copyProperties(attrGroupEntity, attrGroupVO);
        // 设置分类路径
        attrGroupVO.setCatelogPath(catelogPath);

        return attrGroupVO;
    }

    @Override
    public List<AttrRespVO> getAttrByGroupId(Long groupId) {

        List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrAttrgroupRelationService.lambdaQuery()
                .eq(AttrAttrgroupRelationEntity::getAttrGroupId, groupId).list();

        if (attrAttrgroupRelationEntities.isEmpty()) return Collections.emptyList();

        LinkedList<AttrRespVO> attrRespVOS = new LinkedList<>();
        attrAttrgroupRelationEntities.forEach(attrAttrgroupRelationEntity -> {
            AttrEntity attrEntity = attrService.getById(attrAttrgroupRelationEntity.getAttrId());
            if (attrEntity != null)
                attrRespVOS.add(BeanUtil.copyProperties(attrEntity, AttrRespVO.class));
        });


        return attrRespVOS;
    }

    @Override
    @Transactional
    public void deleteAttrRelation(List<AttrAttrgroupRelationRestVO> relationRestVOS) {
        relationRestVOS.forEach(relationRestVO -> {
            // 删除属性关系
            // TODO 删除属性关系 - 视频未作
/*            boolean removed = attrService.removeById(relationRestVO.getAttrId());
            boolean updated = attrService.lambdaUpdate()
                    .set(AttrEntity::getCatelogId, null)
                    .eq(AttrEntity::getAttrId, relationRestVO.getAttrId())
                    .update();
            if (!updated)
                throw new RuntimeException("属性关系删除失败");*/

            // 删除pms_attr_attrgroup_relation中数据
            // TODO 修改为批量删除 增加性能
            boolean remove = attrAttrgroupRelationService.lambdaUpdate()
                    .eq(AttrAttrgroupRelationEntity::getAttrId, relationRestVO.getAttrId())
                    .eq(AttrAttrgroupRelationEntity::getAttrGroupId, relationRestVO.getAttrGroupId())
                    .remove();
            if (!remove)
                throw new RuntimeException("属性关系删除失败");
        });
    }

    /**
     * 获取没有关联组的属性 - 需保证该属性不被其他组关联和该属性是分组分类是相同的 - catelogId
     *
     * @param groupId 组id
     * @param params  查询参数
     * @return 获取没有关联组的属性
     */
    @Override
    public PageUtils notRelationAttrByGroupId(Long groupId, Map<String, Object> params) {
        String key = (String) params.get("key");
        boolean notEmpty = StrUtil.isNotEmpty(key);
        if (groupId == null) return null;
        // 获取关联表中所有属性id
        List<Long> attrIds = attrAttrgroupRelationService.lambdaQuery().list()
                .stream().map(attrAttrgroupRelationEntity -> {
                    return attrAttrgroupRelationEntity.getAttrId();
                })
                .collect(Collectors.toList());
        // 获取组的分类id
        AttrGroupEntity attrGroupEntity = this.lambdaQuery().eq(AttrGroupEntity::getAttrGroupId, groupId).one();
        if (attrGroupEntity == null) return null;
        IPage<AttrEntity> page = attrService.lambdaQuery()
                .notIn(!attrIds.isEmpty(), AttrEntity::getAttrId, attrIds)
                .eq(AttrEntity::getCatelogId, attrGroupEntity.getCatelogId())
                .eq(AttrEntity::getAttrType, AttrTypeEnum.BASE.getCode())
                .and(!notEmpty, consumer ->
                        consumer.like(AttrEntity::getAttrId, key)
                                .or()
                                .like(AttrEntity::getAttrName, key)
                )
                .page(new Query<AttrEntity>().getPage(params));
        return new PageUtils(page);
    }

    /**
     * 批量保存属性关系
     *
     * @param relationRestVOS
     */
    @Override
    public void saveBatchRelation(List<AttrAttrgroupRelationRestVO> relationRestVOS) {
        List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = BeanUtil.copyToList(relationRestVOS, AttrAttrgroupRelationEntity.class);
        boolean saveBatch = attrAttrgroupRelationService.saveBatch(attrAttrgroupRelationEntities);
        if (!saveBatch)
            throw new RuntimeException("批量保存属性关系失败");
    }

    /**
     * 递归查询分类路径
     *
     * @param catId       分类id
     * @param catelogPath 分类路径
     */
    private void getCatelogPath(Long catId, LinkedList<Long> catelogPath) {

        CategoryEntity category = categoryService.lambdaQuery().eq(CategoryEntity::getCatId, catId).one();
        if (category == null) return;
        if (category.getParentCid() != 0)
            getCatelogPath(category.getParentCid(), catelogPath);

        catelogPath.add(category.getCatId());

    }

}